package framework.io;

import java.io.IOException;
import java.io.OutputStream;

/**
 * 满缓冲刷新流
 */
public class FullBufferOutputStream extends OutputStream {

    protected byte buf[];
    protected int count;
    protected OutputStream out;

    public FullBufferOutputStream(OutputStream out, int size) {
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        this.out = out;
        this.buf = new byte[size];
    }

    private void flushBuffer() throws IOException {
        if (count > 0) {
            out.write(buf, 0, count);
            count = 0;
        }
    }

    public void write(int b) throws IOException {
        // 当缓冲区刚好满时刷新
        if (count == buf.length) {
            flushBuffer();
        }
        buf[count++] = (byte) b;
    }

    public void write(byte b[], int off, int len) throws IOException {
        // 检查参数合法性
        if (b == null) {
            throw new NullPointerException("Write data is null");
        } else if (off < 0) {
            throw new IndexOutOfBoundsException("Offset is negative");
        } else if (len < 1) {
            throw new IndexOutOfBoundsException("Length is negative");
        }
//        else if (off > b.length) {
//            throw new IndexOutOfBoundsException("Offset exceeds buffer length");
//        }

        //
        int remainingData = len;
        int currentOff = off;

        // 循环处理所有数据，直到全部写入
        while (remainingData > 0) {
            // 计算缓冲区剩余空间
            int bufferRemaining = buf.length - count;

            // 如果缓冲区已满，先刷新
            if (bufferRemaining == 0) {
                flushBuffer();
                bufferRemaining = buf.length;
            }

            // 计算本次可写入的字节数（不超过剩余空间和剩余数据量）
            int writeLength = Math.min(remainingData, bufferRemaining);

            // 处理可能的数组越界（当请求的数据超出实际可用数据时）
            if (currentOff + writeLength > b.length) {
                writeLength = b.length - currentOff;
                if (writeLength <= 0) {
                    break; // 没有更多可用数据
                }
            }

            // 写入缓冲区
            System.arraycopy(b, currentOff, buf, count, writeLength);
            count += writeLength;
            currentOff += writeLength;
            remainingData -= writeLength;

            // 当缓冲区刚好满时 刷新
            if (count == buf.length) {
                flushBuffer();
            }
        }
    }

    public void flush() throws IOException {
        // 保持原有逻辑，不主动刷新未满的缓冲区
    }

    @Override
    public void close() throws IOException {
        // 最后调用时，即使缓冲区未满也刷新
        flushBuffer();
    }
}